<?php


namespace App\Services;


use App\Agency;
use App\Extensions\EGrid;
use App\Extensions\Exporters\PatentApplyExporter;
use App\Extensions\Renderable\PatentAgencyDetailRenderAble;
use App\Extensions\Renderable\PatentApplyDetailRenderAble;
use App\Extensions\Renderable\PatentAssessDetailRenderAble;
use App\Extensions\Renderable\PatentExpertsDetailRenderAble;
use App\Models\Department;
use App\PatentApply;
use App\Repositories\PatentApplyRepository;
use App\Setting;
use Carbon\Carbon;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Show;
use Encore\Admin\Widgets\Tab;
use Illuminate\Database\Eloquent\Builder;
use PhpOffice\PhpWord\TemplateProcessor;

class PatentApplyService
{

    public function gridColumns($grid, $role, $status)
    {
        $grid->model()->with(['remarks.user', 'assesses.expert', 'experts', 'department', 'agency', 'user']);
        $grid->model()->where('status', $status)->when($status, function ($query) {
            $query->where('review_status', 1);
        })->when($role == 1, function ($query) {
            $query->where('dept_review_status', 1);
        })->when(request()->get('action') == 'reviewing', function ($query) {
            $query->where('review_status', 0);
        });
        $grid->column('uuid', __('登记编号'))->modal('详情', PatentApplyDetailRenderAble::class);
        $grid->column('patent_name', __('专利名称'));
        $grid->column('patent_type_id', __('专利类型'))->using(patent_type_select_option())->width(80);
        if ($status == 1) {
            $grid->column('patent_sn', __('patent_sn'));
            $grid->column('apply_date', __('申请日'))->sortable()->width(100);
            $grid->column('publication_num', __('公告号'));
            $grid->column('publication_date', __('公告日'))->sortable()->width(100);
            $grid->hideColumns(['score_template', 'table', 'file']);
        }
        $grid->column('charge_person', __('第一发明人'));
        $grid->column('department.name', __('dept_name'));
        if (in_array($role, [0, 1, 2])) {
            $grid->column('agency.company', __('意向代理机构'))->modal('详情', PatentAgencyDetailRenderAble::class);
        }
        if ($status != 1) {
            $grid->column('retrieval_report', '检索报告')->display(function ($value) {
                return $value ? '查看' : '';
            })->link(function ($model) {
                return file_custom_preview_url($model['retrieval_report'], '(检索报告)' . $model['patent_name'], 'show');
            });

            if (config('settings.module.expert_module')) {
//            if ($role == 1) {
//                $grid->column('experts', __('评估专家'))->pluck('name')->implode(',')
//                    ->modal('详情', PatentExpertsDetailRenderAble::class);
//            }
                if ($role == 1 && $grid instanceof EGrid) {
                    $grid->column('score', '综合评分')->display(function ($score) {
                        return $score > 0 ? $score : '';
                    })->layerShow(function ($model) {
                        return admin_route('patent-assesses.index', ['patent_apply_id' => $model['id']]);
                    })->sortable();
                } else {
                    $grid->column('score', '综合评分')->display(function ($score) {
                        return $score > 0 ? $score : '';
                    })->modal('详情', PatentAssessDetailRenderAble::class)->sortable();
                }
            }
//            if (config('settings.patent_s_ratio_show')) {
//                $grid->column('funding', '经费资助(元)')->display(function ($amount) {
//                    return $amount ? number_format($amount) : '';
//                })->tooltip('funding_remark');
//            }
            if (config('settings.module.expert_module')) {
                if (in_array($role, [1, 3])) {
                    $grid->column('score_template', '评分指标')->display(function () {
                        return SettingService::patentPfTemplateATag();
                    });
                }
                $grid->column('table', '评估表')->display(function () {
                    return '下载';
                })->link(function ($model) {
                    return admin_route('files.patent-apply.table', [$model['id'], 'token' => $model->token()]);
                });
            }
            $grid->column('file', '交底书')->display(function ($value) {
                return $value ? '下载' : '';
            })->link(function ($model) {
                return file_custom_preview_url($model['file'], '(交底书)' . $model['patent_name']);
            });
        }
        if (config('admin.patent.apply.cert.show', true)) {
            $grid->column('cert', '专利证书')->display(function ($value) {
                return $value ? '下载' : '';
            })->link(function ($model) {
                return file_custom_preview_url($model['cert'], '(证书)' . $model['patent_name']);
            });
        }
        if (!$status) {
            $admin_review_name = Setting::getReviewName(1);
            $dept_review_name = Setting::getReviewName(2);
            $grid->column('review_status', __('审批状态'))->display(function ($value) use ($admin_review_name, $dept_review_name) {
                if ($value) {
                    return data_get([
                        1 => '<span class="label label-success">' . $admin_review_name . '-通过</span>',
                        2 => '<span class="label label-default">' . $admin_review_name . '-未通过</span>',
                        3 => '<span class="label label-default">' . $admin_review_name . '-退回修改</span>',
                    ], $value);
                } else {
                    return data_get([
                        '<span class="label label-warning">' . $dept_review_name . '-待处理</span>',
                        '<span class="label label-warning">' . $admin_review_name . '-待处理</span>',
                        '<span class="label label-default">' . $dept_review_name . '-未通过</span>',
                    ], $this->dept_review_status);
                }
            });
        }
        $grid->column('user.name', __('提交人'))->width(100);
        $grid->exporter((new PatentApplyExporter())->setRoleType($role));
        $this->quickSearch($grid);
        if ($role != 1) {
            $grid->batchActions(function (Grid\Tools\BatchActions $actions) {
                $actions->disableDeleteAndHodeSelectAll();
            });
            $grid->disableFilter();
        } else {
            $this->filter($grid, $status);
        }
        $grid->hideColumns(['user.name']);
        return $grid;
    }

    public function filter(Grid $grid, $status = 0)
    {
        $grid->filter(function (Grid\Filter $filter) use ($status) {
            $filter->disableIdFilter();
            $filter->column(1 / 2, function (Grid\Filter $filter) use ($status) {
                $filter->where(function (Builder $query) {
                    $query->where('patent_name', 'like', "%$this->input%")
                        ->orWhere('patent_sn', 'like', "%$this->input%")
                        ->orWhere('inventor', 'like', "%$this->input%");
                }, '关键字', 'keywords')->placeholder('专利名称/发明人/专利号');
                $filter->where(function (Builder $query) {
                    $query->where('patent_sn', 'like', "%$this->input%");
                }, '专利号', 'patent_sn');
                if ($status) {
                    $filter->where(function ($query) {
                        $query->whereYear('publication_date', $this->input);
                    }, '公告年份', 'publication_date')->year();
                } else {
                    $filter->equal('year', '申请年份')->year();
                }
            });
            $filter->column(1 / 2, function (Grid\Filter $filter) {
                $filter->equal('department_id', __('dept_name'))->select(Department::all()->pluck('name', 'id'));
                $filter->in('patent_type_id', '专利类型')->checkbox(patent_type_select_option());
                $filter->equal('agency_id', '代理机构')->select(Agency::selectAllOptions());
            });
        });
    }

    public function quickSearch(Grid $grid)
    {
        $grid->quickSearch(function ($query, $value) {
            $query->where(function (Builder $query) use ($value) {
                $query->where('patent_name', 'like', "%$value%")
                    ->orWhere('patent_sn', 'like', "%$value%")
                    ->orWhere('inventor', 'like', "%$value%")
                    ->orWhereHas('department', function ($query) use ($value) {
                        $query->where('name', 'like', "%$value%");
                    })->orWhereHas('agency', function ($query) use ($value) {
                        $query->where('name', 'like', "%$value%");
                    })->orWhereHas('experts', function ($query) use ($value) {
                        $query->where('name', 'like', "%$value%");
                    });
            });
        })->placeholder('关键字');
    }

    public static function detail(PatentApply $model)
    {
        $tab = new Tab();
        $tab->add('基本信息', Admin::show($model, function (Show $show) use ($model) {
            $show->panel()->view('show.tab-panel');
            $show->field('uuid', __('登记编号'));
            $show->field('patent_name', __('Patent name'));
            $show->field('inventor', __('Inventor'));
            $show->field('charge_person', __('专利负责人'));
            $show->field('department.name', __('所属科室'));
            $show->field('contact_person', __('联系人'));
            $show->field('phone', __('联系电话'));
            $show->field('patent_person', __('patent_person'));
            $show->field('other_applicant', __('合作申请单位'));
            $show->field('patent_type_id', __('专利类型'))->using(patent_type_select_option());
            if ($model['patent_type_id'] == 4) {
                $show->field('other_patent_sn', __('国内申请号'));
            } elseif ($model['patent_type_id'] == 5) {
                $show->field('country', __('国家'));
                $show->field('apply_channel', __('途径'));
                $show->field('other_patent_sn', __('申请号'));
            }
            $show->field('file', __('交底书'))->as(function ($val) {
                return $val ? '下载' : '';
            })->link(file_custom_preview_url($model['file'], '(交底书)' . $model['patent_name']));
            $show->field('cert', __('专利证书'))->as(function ($val) {
                return $val ? '下载' : '';
            })->link(file_custom_preview_url($model['cert'], '(证书)' . $model['patent_name']));
            $show->field('dept_review_remark', __('科室意见'));
            $show->field('review_remark', __('院级审核意见'));
        }));
        return $tab;
    }

    public function downloadTable($model)
    {
        $templateProcessor = $this->tableTemplateProcessor($model);
        $res = $templateProcessor->save();
        $content = file_get_contents($res);
        unlink($res);
        return response_stream_download($content, $model['patent_name'] . '(申请前评估表).docx');;
    }

    public function tableTemplateProcessor($model)
    {
        $is_woman = '☑';
        $is_man = '□';
        //实例化 phpword 类
//        $PHPWord = new PhpWord();
        //指定事先制作好的模板文件路径
        $templateProcessor = new TemplateProcessor(public_path("template/register_table_template.docx"));
        $templateProcessor->setValue('org_name', org_name());
        $data = [
            'patent_name'    => $model['patent_name'],
            'inventor'       => $model['inventor'],
            'charge_person'  => $model['charge_person'],
            'contact_person' => $model['contact_person'],
            'phone'          => $model['phone'],
            'department'     => $model->department->name ?? '',

            'applicant#1'       => !$model['other_applicant'] ? $is_woman : $is_man,
            'applicant#2'       => $model['other_applicant'] ? $is_woman : $is_man,
            'applicant#2#other' => $model['other_applicant'] ?: "\r\r\r\r\r\r\r\r",

            'patent_type#1'        => $model['patent_type_id'] == 1 ? $is_woman : $is_man,
            'patent_type#2'        => $model['patent_type_id'] == 2 ? $is_woman : $is_man,
            'patent_type#3'        => $model['patent_type_id'] == 3 ? $is_woman : $is_man,
            'patent_type#4'        => $model['patent_type_id'] == 4 ? $is_woman : $is_man,
            'patent_type#4#code'   => $model['patent_type_id'] == 4 && $model['other_patent_sn'] ? $model['other_patent_sn'] : "CN\r\r\r\r\r\r\r\r",
            'patent_type#5'        => $model['patent_type_id'] == 5 ? $is_woman : $is_man,
            'patent_type#5#county' => $model['county'] ?: "\r\r\r ",
            'patent_type#5#1'      => $model['apply_channel'] == 1 ? $is_woman : $is_man,
            'patent_type#5#2'      => $model['apply_channel'] == 2 ? $is_woman : $is_man,
            'patent_type#5#code'   => $model['apply_channel'] == 2 && $model['other_patent_sn'] ? $model['other_patent_sn'] : "\r\r\r\r\r",

            'patent_attr'      => $this->getSelectTemplate(PatentApply::PATENT_ATTR, $model['patent_attr']),
            'te_source'        => $this->getSelectTemplate(PatentApply::TE_SOURCE, $model['te_source']),
            'te_source_remark' => $model['te_source_remark'] ?: '',

            'te_field'        => $this->getSelectTemplate(PatentApply::TE_FIELD, $model['te_field']),
            'te_field_remark' => $model['te_field_remark'] ?: "\r\r",

            'te_maturity'        => $this->getSelectTemplate(PatentApply::TE_MATURITY, $model['te_maturity']),
            'te_maturity_remark' => $model['te_maturity_remark'] ?: "\r\r\r",

            'te_innovate' => $this->getSelectTemplate(PatentApply::TE_INNOVATE, $model['te_innovate']),

            'ptm'        => $this->getSelectTemplate(PatentApply::PTM, $model['ptm']),
            'ptm_remark' => $model['ptm_remark'] ?: "\r\r\r\r",

            'novelty'      => $this->getSelectTemplate(PatentApply::NOVELTY, $model['novelty'], "\r\r"),
            'creativity'   => $this->getSelectTemplate(PatentApply::CREATIVITY, $model['creativity'], "\r\r"),
            'practicality' => $this->getSelectTemplate(PatentApply::PRACTICALITY, $model['practicality'], "<w:br/>\r\r\r\r"),
            'prospect'     => $this->getSelectTemplate(PatentApply::PROSPECT, $model['prospect'], "\r\r"),
            'created_at'   => date('Y年m月d日', Carbon::parse($model['created_at'])->getTimestamp()),

            'cts'                => $model['cts'],
            'ownership_divide#1' => $model['ownership_divide'] == 1 ? $is_woman : $is_man,
            'ownership_divide#2' => $model['ownership_divide'] == 2 ? $is_woman : $is_man,

            'dept_review#1' => $model['dept_review_status'] == 1 ? $is_woman : $is_man,
            'dept_review#2' => $model['dept_review_status'] == 2 ? $is_woman : $is_man,

            'dept_review_remark' => $model['dept_review_remark'] ?? "",

            'retrieval_remark'  => $model['retrieval_remark'] ?? '',
            'evaluation_remark' => $model['evaluation_remark'] ?? '',
        ];
        $templateProcessor->setValues($data);
        return $templateProcessor;
    }


    public function getSelectTemplate($data, $select, $empty = "\r")
    {
        $is_woman = '☑';
        $is_man = '□';
        $str = '';
        $end = end($data);
        foreach ($data as $key => $value) {
            $check = $key == $select ? $is_woman : $is_man;
            $str .= $check;
            $str .= $value;
            if ($end != $value) {
                $str .= $empty;
            }
        }
        return $str;
    }

    public function form($model = null)
    {
        $user = Admin::user();
        $form = $this->repository()->form();
        $form->text('patent_name', __('专利名称'))->required();
        $form->text('inventor', __('全体发明人'))->required();
        $form->text('charge_person', __('第一发明人'))->required()->default($user->name);
        $form->text('contact_person', __('联系人'))->required()->default($user->name)->width('150px');
        $form->mobile('phone', __('联系电话'))->required()->default($user->mobile);
        $form->text('patent_person', __('专利权人'))->required()->default(org_name());
        $form->text('other_applicant', __('合作申请单位'))->help('合作申请，其他申请人');
        $form->radio('patent_type_id', '专利类别')->required()->options(patent_type_select_option())
            ->when(4, function (Form $form) {
                $form->text('other_patent_sn', '国内申请号')->width('200px');
            })->when(5, function (Form $form) {
                $form->text('country', '具体国家')->width('200px');
                $form->radio('apply_channel', '申请途径')->default(0)->options(PatentApply::APPLY_CHANNEL);
                $form->text('other_patent_sn', '申请号')->width('200px');
            });
        $form->radio('te_source', '技术来源')->options(PatentApply::TE_SOURCE)->required();
        $pg_data = config('score_field.patent', []) ?: [];
        foreach ($pg_data as $datum) {
            $form->embeds($datum['column'], $datum['title'], function (Form\EmbeddedForm $form) use ($datum) {
                foreach ($datum['group'] as $item) {
                    if (in_array($item['form'], ['radio', 'select'])) {
                        $form->radio($item['column'], $item['label'])->options($item['options'])->required();
                    } elseif (in_array($item['form'], ['text', 'textarea'])) {
                        $form->{$item['form']}($item['column'], $item['label'])->required();
                    }
                }
            });
        }
        $form->radio('ownership_divide', '是否所有权分割')->options([1 => '是', 2 => '否'])->default(2)->required();
        $form->file('file', __('技术交底书'))->uniqueName()->hidePreview()->required();
        $isAgentForm = $form->radio('is_agent', '是否走代理')->options(['否', '是'])->required()
            ->when(1, function (Form $form) {
                $form->select('agency_id', '意向代理机构')->options(Agency::selectOptions())->rules('required_if:is_agent,1')->setLabelClass(['asterisk']);
            })->when(0, function (Form $form) {
                $form->file('retrieval_report', '检索报告')->uniqueName()->hidePreview()->help('上传第三方机构出具的查新检索报告，须明确是否具有专利性')->setLabelClass(['asterisk']);
            });
        if ($form->isCreating()) {
            $isAgentForm->default(request()->session()->get('_old_input')['is_agent'] ?? 1);
        }
        $form->hidden('applicant');
        $form->hidden('review_status');
        $form->hidden('dept_review_status');
        $form->hidden('review_remark');
        $form->hidden('file_time');
        if ($form->isCreating()) {
            $form->hidden('user_id', __('用户ID'));
            $form->hidden('department_id');
            $form->hidden('uuid', __('编号'));
            $form->hidden('serial_number')->default(0);
            $form->hidden('year')->default(date('Y'));
        }
        $form->saving(function (Form $form) use ($user) {
            if ($form->isCreating()) {
                $form->user_id = $user->id;
                $form->department_id = $user->department_id;
                $form->year = date('Y');
                $form->serial_number = $this->repository()->getSerialNumber($form->year);
                $form->uuid = $this->repository()->getApplyNewCode($form->year, $form->serial_number);
            }
//            if (in_array($user['role_type'], [1, 2])) {
//                $form->review_status = 0;
//                $form->dept_review_status = 1;
//            } else {
//                $form->review_status = 0;
//                $form->dept_review_status = 0;
//            }
            $form->review_status = 0;
            $form->dept_review_status = 0;
            $form->review_remark = '';
            $form->applicant = $form->patent_person;
            if ($form->other_applicant) {
                $form->applicant = $form->patent_person . ',' . $form->other_applicant;
            }
            if ($form->is_agent != 1) {
                if (!$form->model()->retrieval_report && !$form->retrieval_report) {
                    return back()->withInput(request()->all())->withInput([
                        'retrieval_report' => '不走代理请上传第三方机构出具的查新检索报告'
                    ]);
                }
                $form->agency_id = 0;
            }
            if ($form->file) {
                $form->file_time = Carbon::now();
            }
        });
        return $form;
    }

    public function repository(): PatentApplyRepository
    {
        return app(PatentApplyRepository::class);
    }

}
